using ErrorCode;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using System.Net;

namespace RabbitTraceability.Api.Filters
{
    /// <summary>
    /// 全局异常处理过滤器
    /// </summary>
    public class GlobalExceptionFilter : IExceptionFilter
    {
        private readonly ILogger<GlobalExceptionFilter> _logger;
        private readonly IWebHostEnvironment _env;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="env">Web主机环境</param>
        public GlobalExceptionFilter(ILogger<GlobalExceptionFilter> logger, IWebHostEnvironment env)
        {
            _logger = logger;
            _env = env;
        }

        /// <summary>
        /// 处理异常
        /// </summary>
        /// <param name="context">异常上下文</param>
        public void OnException(ExceptionContext context)
        {
            // 记录异常详情
            _logger.LogError(context.Exception, "未处理的异常: {Message}", context.Exception.Message);

            // 准备返回结果
            ApiResult result;
            HttpStatusCode httpStatusCode;

            // 根据异常类型设置状态码和错误信息
            if (context.Exception is ApiException apiEx)
            {
                // 处理自定义API异常
                httpStatusCode = GetHttpStatusCode(apiEx.Code);
                result = ApiResult.Error(apiEx.Code, apiEx.Message);
            }
            else if (context.Exception is ArgumentException)
            {
                // 处理参数异常
                httpStatusCode = HttpStatusCode.BadRequest;
                result = ApiResult.Error(ResultCode.参数错误, context.Exception.Message);
            }
            else if (context.Exception is InvalidOperationException)
            {
                // 处理操作异常
                httpStatusCode = HttpStatusCode.Conflict;
                result = ApiResult.Error(ResultCode.操作失败, context.Exception.Message);
            }
            else if (context.Exception is UnauthorizedAccessException)
            {
                // 处理未授权异常
                httpStatusCode = HttpStatusCode.Unauthorized;
                result = ApiResult.Error(ResultCode.未授权, "未授权的操作");
            }
            else if (context.Exception is KeyNotFoundException)
            {
                // 处理数据不存在异常
                httpStatusCode = HttpStatusCode.NotFound;
                result = ApiResult.Error(ResultCode.数据不存在, context.Exception.Message);
            }
            else
            {
                // 处理其他未知异常
                httpStatusCode = HttpStatusCode.InternalServerError;
                
                // 只在开发环境中显示详细错误信息
                string errorMessage = _env.IsDevelopment() ? 
                                     context.Exception.Message : 
                                     "服务器内部错误，请稍后再试";
                
                result = ApiResult.Error(ResultCode.服务器错误, errorMessage);
                
                // 记录详细的堆栈信息
                _logger.LogError(context.Exception, "服务器错误详情: {StackTrace}", context.Exception.StackTrace);
            }

            // 设置响应
            context.Result = new ObjectResult(result)
            {
                StatusCode = (int)httpStatusCode
            };

            // 标记异常已处理
            context.ExceptionHandled = true;
        }

        /// <summary>
        /// 根据结果码获取HTTP状态码
        /// </summary>
        /// <param name="code">结果码</param>
        /// <returns>HTTP状态码</returns>
        private static HttpStatusCode GetHttpStatusCode(ResultCode code)
        {
            return code switch
            {
                ResultCode.成功 => HttpStatusCode.OK,
                ResultCode.参数错误 => HttpStatusCode.BadRequest,
                ResultCode.未授权 => HttpStatusCode.Unauthorized,
                ResultCode.禁止访问 => HttpStatusCode.Forbidden,
                ResultCode.资源不存在 => HttpStatusCode.NotFound,
                ResultCode.服务器错误 => HttpStatusCode.InternalServerError,
                ResultCode.服务不可用 => HttpStatusCode.ServiceUnavailable,
                ResultCode.数据已存在 => HttpStatusCode.Conflict,
                ResultCode.数据不存在 => HttpStatusCode.NotFound,
                ResultCode.操作失败 => HttpStatusCode.BadRequest,
                ResultCode.UserNotFound => HttpStatusCode.NotFound,
                ResultCode.PasswordIncorrect => HttpStatusCode.Unauthorized,
                ResultCode.UserDisabled => HttpStatusCode.Forbidden,
                ResultCode.UserNameExists => HttpStatusCode.Conflict,
                ResultCode.InvalidToken => HttpStatusCode.Unauthorized,
                ResultCode.TokenExpired => HttpStatusCode.Unauthorized,
                ResultCode.DuplicateProductionBatch => HttpStatusCode.Conflict,
                _ => HttpStatusCode.BadRequest
            };
        }
    }
} 